package com.northpool.operator.cicd.ssh;

import cn.hutool.core.io.FileUtil;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.Vector;

public class JschUtils {
    private JSch jsch;
    private Session session;

    /**
     * 连接到指定的IP
     *
     * @throws JSchException
     */
    public void connect(String user, String passwd, String host, int port) throws JSchException {
        jsch = new JSch();// 创建JSch对象
        session = jsch.getSession(user, host, port);// 根据用户名、主机ip、端口号获取一个Session对象
        session.setPassword(passwd);// 设置密码

        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);// 为Session对象设置properties
        session.setTimeout(3000);// 设置超时
        session.connect();// 通过Session建立连接
    }

    /**
     * 关闭连接
     */
    public void close() {
        session.disconnect();
    }

    /**
     * 执行相关的命令
     *
     * @throws JSchException
     */
    public String execCmd(String command) throws JSchException {
        BufferedReader reader = null;
        Channel channel = null;
        try {
            StringBuilder sb = new StringBuilder();
            if (command != null) {
                channel = session.openChannel("exec");
                ((ChannelExec) channel).setCommand(command);
                // ((ChannelExec) channel).setErrStream(System.err);
                channel.connect();

                InputStream in = channel.getInputStream();
                reader = new BufferedReader(new InputStreamReader(in));
                String buf = null;
                while ((buf = reader.readLine()) != null) {
                    sb.append(buf);
                }
                return sb.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSchException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            channel.disconnect();
        }
        return "";
    }

    /**
     * 上传文件
     *
     * @param directory
     *            上传的目录
     * @param uploadFile
     *            要上传的文件
     * @throws JSchException
     * @throws SftpException
     * @throws FileNotFoundException
     */
    public void upload(String directory, String uploadFile, SftpProgressMonitor monitor) throws JSchException, FileNotFoundException, SftpException {
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        channelSftp.cd(directory);
        File file = new File(uploadFile);
        if (file.isDirectory()) {
            throw new RuntimeException("文件夹不能上传, 只允许上传单个文件");
        }
        channelSftp.put(FileUtil.getInputStream(file), file.getName(), monitor);
    }

    /**
     * 下载文件
     *
     * @param src
     * @param dst
     * @throws JSchException
     * @throws SftpException
     */
    public void download(String src, String dst) throws JSchException, SftpException {
        // src linux服务器文件地址，dst 本地存放地址
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        channelSftp.get(src, dst);
        channelSftp.quit();
    }

    /**
     * 删除文件
     *
     * @param directory
     *            要删除文件所在目录
     * @param deleteFile
     *            要删除的文件
     * @throws SftpException
     * @throws JSchException
     */
    public void delete(String directory, String deleteFile) throws SftpException, JSchException {
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        channelSftp.cd(directory);
        channelSftp.rm(deleteFile);
    }

    /**
     * 重命名文件
     *
     * @param oldpath
     *            旧路径
     * @param newpath
     *            新路径
     * @throws SftpException
     * @throws JSchException
     */
    public void rename(String oldpath, String newpath) throws SftpException, JSchException {
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        channelSftp.rename(oldpath, newpath);
    }

    /**
     * 列出目录下的文件
     *
     * @param directory
     *            要列出的目录
     * @return
     * @throws SftpException
     * @throws JSchException
     */
    @SuppressWarnings("rawtypes")
    public Vector listFiles(String directory) throws JSchException, SftpException {
        ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
        return channelSftp.ls(directory);
    }
}